package com.lk.security.authentication.session;

import com.lk.base.result.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.web.session.InvalidSessionStrategy;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: lk-security-parent
 * @description: 当session失效后的处理逻辑
 * @author: Aspirin
 * @create: 2020-06-02 21:59
 */
public class CustomInvalidSessionStrategy implements InvalidSessionStrategy {

  private static final Logger logger = LoggerFactory.getLogger(CustomInvalidSessionStrategy.class);

  /** 因为CustomInvalidSessionStrategy不在容器中，不可以使用@Autowired */
  private final SessionRegistry sessionRegistry;

  public CustomInvalidSessionStrategy(SessionRegistry sessionRegistry) {
    this.sessionRegistry = sessionRegistry;
  }

  /**
   * 1. 清除session 2. 删除cookie
   *
   * @param request
   * @param response
   * @throws IOException
   */
  @Override
  public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
      throws IOException {

    /*getSession().getId(): 无session会创建新的session; getRequestedSessionId(): 获取的浏览器的cookie的session*/
    logger.info("getSession().getId():{}", request.getSession().getId());
    logger.info("getRequestedSessionId():{}", request.getRequestedSessionId());
    sessionRegistry.removeSessionInformation(request.getRequestedSessionId());

    // 将浏览器的cookie删除
    cancelCookie(request, response);

    Result result = Result.build(HttpStatus.UNAUTHORIZED.value(), "登录已超时，请重新登录");
    response.setContentType("application/json;charset=utf-8");
    response.getWriter().write(result.toJsonString());
  }

  protected void cancelCookie(HttpServletRequest request, HttpServletResponse response) {
    logger.debug("Cancelling cookie");
    Cookie cookie = new Cookie("JSESSIONID", null);
    cookie.setMaxAge(0);
    cookie.setPath(getCookiePath(request));
    response.addCookie(cookie);
  }

  private String getCookiePath(HttpServletRequest request) {
    String contextPath = request.getContextPath();
    return contextPath.length() > 0 ? contextPath : "/";
  }
}
